﻿/*
* BaseHero.h
*
* 武将基类
*
* create date: 2014.4.11
* create by: leo
*
*/

#ifndef _BASEHERO_H_
#define _BASEHERO_H_

#include "cocos2d.h"
#include "../Common.h"

#include "../armatures/HeroArmature.h"
#include "../skill/BaseSkill.h"
#include "../corps/BaseCorps.h"
#include "HeroStateListener.h"

class CWalking;
class CWaiting;
class CBeAttacked;
class CCommonAttack;
class CDying;
class CVictory;

class CBaseHero : public cocos2d::CCNode
{
public:
	typedef enum
	{
		RIGHT,
		LEFT
	} Direction;

	typedef struct Param
	{
		int ID;
		cocos2d::CCString Name; // 姓名
		int Level; // 等级
		int Exp; // 当前经验
		int Race; // 国别
		int Rank; // 军衔
		int Type; // 武将类型
		int StarRank; // 星级

		int MaxHp; // 最大气血
		int Hp; // 气血
		int Str; // 武力
		int Intell; // 智力
		int Crit; // 暴击
//		int Def; // 防御
//		int Hit; // 命中
//		int Dodge; // 闪避
		int Revert; // 恢复
		int Armor; // 护甲
		int MagicResist; // 魔抗
		int CritResist; // 抗暴

		int Rage; // 怒气

		int HpGrowth; // 气血成长
		int StrGrowth; // 物理成长
		int IntellGrowth; // 智力成长

		int AttSpeed; // 攻速
		int MoveSpeed; // 移动速度

		CHeroArmature* Armature; // 武将动画集
		CHeroArmature* ShadowArmature; // 武将阴影动画集
		cocos2d::CCString ArmaResPath; // 动画集文件名
		cocos2d::CCString ArmaName; // 动画集名

		std::vector<int> SkillIndices; // 技能编号
		std::vector<CBaseSkill::Param*> SkillParams; // 技能参数
		std::vector<int> SkillSequences; // 技能顺序

        float Scale; // 缩放比

		Param()
		: ID(0),
		  Level(0),
		  Exp(0),
		  Race(0),
		  Rank(0),
		  Type(0),
		  StarRank(0),
		  Hp(0),
		  MaxHp(0),
		  Str(0),
		  Intell(0),
		  Crit(0),
		  Revert(0),
		  Armor(0),
		  MagicResist(0),
		  CritResist(0),
		  Rage(0),
		  HpGrowth(0),
		  StrGrowth(0),
		  IntellGrowth(0),
		  AttSpeed(0),
		  MoveSpeed(0),
		  Armature(NULL),
          Scale(1)
		{}

		Param(int id,
			cocos2d::CCString& name,
			int level,
			int exp,
			int race,
			int rank,
			int type,
			int starRank,
			int Hp,
			int str,
			int intell,
			int crit,
			int revert,
			int armor,
			int magicResist,
			int critResist,
			int rage,
			int hpGrowth,
			int strGrowth,
			int intellGrowth,
			int attSpeed,
			int moveSpeed,
			CHeroArmature* armature,
            float scale)
		: ID(id),
		  Name(name),
		  Level(level),
		  Exp(exp),
		  Race(race),
		  Rank(rank),
		  Type(type),
		  StarRank(starRank),
		  MaxHp(Hp),
		  Hp(Hp),
		  Str(str),
		  Intell(intell),
		  Crit(crit),
		  Revert(revert),
		  Armor(armor),
		  MagicResist(magicResist),
		  CritResist(critResist),
		  Rage(rage),
		  HpGrowth(hpGrowth),
		  StrGrowth(strGrowth),
		  IntellGrowth(intellGrowth),
		  AttSpeed(attSpeed),
		  MoveSpeed(moveSpeed),
		  Armature(armature),
          Scale(scale)
		{}

        ~Param()
        {}

	} Param;

public:
	static CBaseHero* create(const char* paramString);

public:
	/*
	 * 改变武将状态
	 *
	 * state 状态
	 *
	 */
	virtual void changeStateTo(int state);

	/*
	 * 武将行走
	 *
	 * pos 终点
	 */
	virtual void walkingTo(const cocos2d::CCPoint& pos/*, cocos2d::CCObject* callbackObj, cocos2d::SEL_CallFuncO callback*/);
	virtual void stopWalking();
	virtual void registerWalkingSkill(CWalking& walking);
	/*
	 * 切换到待机
	 */
	virtual void waiting();
	virtual void registerWaitingSkill(CWaiting& waiting);
	/*
	 * 切换到被攻击
	 */
	virtual void beAttacked(CBaseSkill& skill);
	virtual void registerBeAttackedSkill(CBeAttacked& beAttacked);
	/*
	 * 切换到死亡
	 */
	virtual void dying();
    virtual void registerDyingSkill(CDying& dying);

    /*
     * 胜利
     */
    virtual void victory();
    virtual void registerVictorySkill(CVictory& victory);


	virtual void registerCommonAttackSkill(CCommonAttack& attack);

	virtual void registerSkill(CBaseSkill& skill, CBaseSkill::Type type);
	/*
	 * 预加载资源
	 */
	virtual void preloadRes();
	/*
	 * 卸载资源
	 */
	virtual void unloadRes();
	/*
	 * 是否已加载资源
	 *
	 * return true:已加载;false:未加载
	 */
	virtual bool isResLoaded();

	virtual void setCorps(CBaseCorps& mCorps);
	virtual void setEnemyCorps(CBaseCorps& mCorps);
	virtual CBaseCorps* getCorps();
	virtual CBaseCorps* getEnemyCorps();

	virtual int getMoveSpeed();

	virtual bool isAlive();
	virtual float getArmatureScale();

	virtual void setCorpsPos(CBaseCorps::CorpsPos pos);
	virtual CBaseCorps::CorpsPos getCorpsPos();

	/*
	 * 设置状态改变时回调
	 */
	void addStateListener(IBaseHeroStateListener& listener);
	void removeStateListener(IBaseHeroStateListener& listener);

	cocos2d::CCPoint getAttackPoint();

	int getCrit();

	void turnTo(Direction dir);

public:
	virtual void update(float delta);

	virtual const cocos2d::CCSize& getContentSize() const;
	virtual void setPosition(const cocos2d::CCPoint &position);

protected:
	CBaseHero();
	CBaseHero(Param& param);
	virtual ~CBaseHero();

	void onSkillFinish(cocos2d::CCObject* skill);
	void onDying(cocos2d::CCObject* skill);

	void removeNode(cocos2d::CCNode* node);

protected:
	class CEmptyStateListener : public IBaseHeroStateListener
	{
	public:
		void onPositionChange(CBaseHero& hero) {}
		void onDied(CBaseHero& hero) {}
	} EmptyStateListener;

protected:
	CFilePathProvider& mFilePathProv;
	bool mResLoaded;
	bool mSkillActing;
	bool mMoving;
	std::list<IBaseHeroStateListener*> mStateListeners;
	std::list<IBaseHeroStateListener*> mNeedAddStateListeners;
	std::list<IBaseHeroStateListener*> mNeedRemoveStateListeners;
	CBaseCorps::CorpsPos mCorpsPos; // 队伍位置
	CBaseCorps* mBelongCorps; // 属于队伍
	CBaseCorps* mEnemyCorps; // 敌人队伍
	Param mParam; // 武将属性
	Direction mDir; // 方向

	float mElapsedTime; // 距离上次施法流逝时间（秒）

	std::vector<CBaseSkill*> mSkills; // 武将技能
	std::vector<int> mSkillArmatureIndices; // 武将技能
	cocos2d::CCArray mSkillSequence; // 技能释放顺序
	unsigned int mNextSkillIndex; // 下一个技能序号

	cocos2d::CCLayerColor* mHpBarBg;
	cocos2d::CCLayerColor* mHpBar;

	float mSkewAniValue;
	float mSkewAniValueStep;
};

#endif // _BASEHERO_H_
